package hehe.validation.annotation;

import hehe.validation.base.Rule;
import hehe.validation.util.Scan;
import hehe.validation.validator.ValidAlias;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 注解验证管理类
 *<B>说明：</B>
 *<pre>
 * 略
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class ValidAnnotation
{
    /**
     * 注解验证规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected static Map<Class,Map<Field,List<Rule>>> annotationRules = new HashMap<>();

    protected static Map<Class,List<Rule>> ruleList = new HashMap<>();


    public static String packageName;
    /**
     * 获取当前类包名
     *<B>说明：</B>
     *<pre>
     * 　略
     *</pre>
     * @return 当前包名
     */
    public static String getPackageName()
    {

        if (packageName != null) {
            return packageName;
        }

        packageName = new Object()    {
            public String getPackageName()
            {
                Class onwClass = this.getClass();
                Package dbPackage =  onwClass.getPackage();
                return  dbPackage.getName();
            }
        }.getPackageName();

        return packageName;
    }

    /**
     * 获取注解字段最新验证规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static Rule getLastRule(Class clazz,Field field)
    {
        if (!annotationRules.containsKey(clazz)) {
            return null;
        }

        if (!annotationRules.get(clazz).containsKey(field)) {
            return null;
        }

        int size = annotationRules.get(clazz).get(field).size();

        if (size == 0) {
            return null;
        }

        return annotationRules.get(clazz).get(field).get(size - 1);
    }

    /**
     * 添加注解验证规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static void addRule(Class clazz,Field field,Rule rule)
    {

        if (!annotationRules.containsKey(clazz) || !annotationRules.get(clazz).containsKey(field)) {
            Map<Field,List<Rule>> annotationRule = new HashMap<>();
            List<Rule> rules = new ArrayList<>();
            rules.add(rule);
            annotationRule.put(field,rules);
            annotationRules.put(clazz,annotationRule);
            return;
        }

        annotationRules.get(clazz).get(field).add(rule);

        return;
    }

    /**
     * 构建注解验证规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static void buildAnnotationRule(Class targetclazz) throws Exception
    {
        // 解析注解
        AnnotationMetadata annotationMetadata = new AnnotationMetadata(targetclazz);
        annotationMetadata.parseFieldAnnotation(ValidAlias.getAllValidatorsAlias());
    }

    /**
     * 获取注解验证规则
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static List<Rule> getRules(Class targetclazz)
    {
        try {
            if (!annotationRules.containsKey(targetclazz)) {
                ValidAnnotation.buildAnnotationRule(targetclazz);
            }

            if (ruleList.containsKey(targetclazz)) {
                return ruleList.get(targetclazz);
            }

            Map<Field,List<Rule>> annRules =  annotationRules.get(targetclazz);
            List<Rule> rules = new ArrayList<>();
            for (Map.Entry<Field,List<Rule>> ruleEntry : annRules.entrySet()) {
                rules.addAll(ruleEntry.getValue());
            }

            ruleList.put(targetclazz,rules);

            return rules;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 扫描验证器
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static void scanValidator(String basePackage)
    {
        List<Class<?>> ClazzList = Scan.create(basePackage).start();
        for (Class<?> clazz:ClazzList) {
            // 查找注解
            ValidatorAlias validatorAlias = clazz.getAnnotation(ValidatorAlias.class);
            if (validatorAlias != null) {
                ValidAlias.putValidatorAlias(validatorAlias.alias(),clazz);
            }
        }
    }

    /**
     * 扫描验证器注解
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public static void scanAnnotation(String basePackage)
    {
        List<Class<?>> ClazzList = Scan.create(basePackage).start();
        for (Class<?> annotationClazz:ClazzList) {
            // 查找注解
            Constraint constraint = annotationClazz.getAnnotation(Constraint.class);
            if (constraint != null) {
                ValidAlias.registerAnnotation(annotationClazz);
                Class<?>[] validators = constraint.validator();
                if (validators != null && validators.length > 0) {
                    Class<?> validatorClazz = validators[0];
                    ValidatorAlias validatorAlias = validatorClazz.getAnnotation(ValidatorAlias.class);
                    if (validatorAlias != null) {
                        ValidAlias.putValidatorAnnotationRelation(annotationClazz,validatorAlias.alias());
                    }
                }
            }
        }
    }

}
